/* Library: UWA Data

_Copyright 2006-2007 Netvibes. All rights reserved._

*/

if (typeof UWA == "undefined") var UWA = {};

if (typeof UWA.proxies == "undefined") {
  
  UWA.proxies = {
    'api'  : NV_PATH + 'proxy/api2Proxy.php',
    'rss'  : NV_PATH + 'proxy/xmlProxy.php',
    'ajax' : NV_PATH + 'proxy/ajaxProxy.php',
    'feed' : NV_PATH + 'proxy/feedProxy.php',
    'xml'  : NV_PATH + 'data/xml/'
  }
  
}


if (typeof UWA.Json == "undefined") UWA.Json = {};

  /* Method: request

  Builds a "JSON" request, by creating a temporary Javascript tag to access the URL.

  Parameters:
  * String - url: the URL of the data source,
  * Collection{Object} - request: an Object collection representing a request (proxy and callback keys).

  Returns:
  * Nothing,

  Example:
  (start code)
  ...
  UWA.Json.request(url, { callback: callback } );
  ...
  (end)
  This method is used by the <UWA.Data> class. In Modules, you usually use the <UWA.Data> class.
  */  

UWA.Json.request = function(url, request) {

  var varname = 'json';
  
  if (request.context && request.context[0]) varname += request.context[0];
  else varname += Math.round(1000*1000*Math.random());

  eval(varname + '= false');

  url += '&object=' + varname ;

  var script = document.createElement('script');
  script.setAttribute('type', 'text/javascript');
  script.src = url;
  var head = document.getElementsByTagName('head')[0];
  var insert = head.appendChild(script);

  if (typeof request.onComplete == "undefined") UWA.log('no callback set');

  var callback = request.onComplete;

  var myCallback = function(c){ return function(j) { callback(j, c) } }(request.context);

  var interval = setInterval( ( function() {
    eval('var json = ' + varname);
    if (json) {
      try {
        myCallback(json);
      } catch(e) {
        UWA.log(e);
      }
      insert.parentNode.removeChild(insert);
      clearInterval(interval);
    }
  } ).bind(this), 100);

}

UWA.Data = {
  
  useJsonRequest: false,
  
  /* Method: getFeed

  This method is used to get the content of a feed, in a JSON format.

  Parameters:
  * String - url: the URL of the feed data source,
  * Function - callback: the callback method that will be fired when the request is succesful. 
  This method *must have one parameter* to receive the feed (JSON format) returned by the request.

  Returns:
  * Nothing, but the callback method is fired if the request is successful, and receives the feed as parameter.
  
  Example:
  (start code)
  ...
  UWA.Data.getFeed(this.getValue('http://feeds.feedburner.com/NetvibesDevBlog'), myModule.display.bind(this));
  ...
  myModule.display = function(aFeed) {
  ... 
  }
  ...
  (end)
  In this example, the callback method is named "display", and is used to display the feed content.
  *Please note the ".bind(this)" usage when providing a callback method.*
  */
  getFeed: function(url, callback) {
    if (typeof UWA.feedCallbackType == "undefined") UWA.feedCallbackType = "json";
    return this.request(url, { method : 'GET', proxy: 'feed', type: UWA.feedCallbackType, onComplete: callback } );
  },

  /* Method: getXml

  This method is used to get the content of an external XML data source. 
  It can be used to retrieve the content of a feed in XML format.

  Parameters:
  * String - url: the URL of the feed data source,
  * Function - callback: the callback method that will be fired when the request is succesful. 
  This method *must have one parameter* to receive the XML content returned by the request.

  Returns:
  * Nothing, but the callback method is fired if the request is successful, and receives the XML content as parameter.
  
  Example:
  (start code)
  ...
  UWA.Data.getXml("http://digg.com/rss/index.xml", myModule.parse.bind(this));
  ...
  myModule.parse = function( xml) {
  ...
  }
  (end)
  */ 
  getXml: function(url, callback) {
    return this.request(url, { method : 'GET', proxy: 'ajax', type: 'xml', onComplete: callback } );
  },
  
  /* to document */
  getText: function(url, callback) {
    return this.request(url, { method : 'GET', proxy: 'ajax', type: 'text', onComplete: callback } );
  },
  
  /* to document */
  getJson: function(url, callback) {
    return this.request(url, { method : 'GET', proxy: 'ajax', type: 'json', onComplete: callback } );
  },

  /* Method: getModule

  This method is used to get the content of an external module, in XML format.

  Parameters:
  * String - url: the URL of the feed data source,
  * Function - callback: the callback method that will be fired when the request is succesful. 
  This method *must have one parameter* to receive the module content returned by the request.

  Returns:
  * Nothing, but the callback method is fired if the request is successful, and receives the module content as parameter.
  */  
  getModule: function(url, callback, id) {
    if (UWA.proxies['api']) {
      url = UWA.proxies['api'] + '?moduleUrl=' + encodeURIComponent(url);
      if (id) url += '&moduleId=' + id;
      return this.request(url, { method : 'GET', type: 'xml', onComplete: callback } );
    }
    UWA.log('no proxy URL set for module'); return false;
  },

  /* to document */
  request: function(url, request) {
    
    if (typeof request == 'undefined') request = {};
    
    if (typeof request.method == 'undefined') request.method = 'GET';

    if (request.method == 'DELETE' || request.method == 'PUT') {
      // TODO: Restrict this patch to Opera and Safari
      if (typeof request.headers  == 'undefined') request.headers = {};
      request.headers['X-Requested-Method'] = request.method;
      request.method = 'POST';
    }

    if (typeof request.proxy == 'undefined') {
      if (url.substr(0, 4) == "http" && url.indexOf("http://" + location.hostname) == -1 ) request.proxy = 'ajax';
    }
    
    if (typeof request.type == 'undefined') request.type = 'text';
    
    if (UWA.proxies[request.proxy]) {
      url = UWA.proxies[request.proxy] + '?url=' + encodeURIComponent(url);
      if (request.proxy == "feed" && request.shortFeed != false) url += "&rss=1";
    } else if (request.proxy) {
      UWA.log('no proxy URL set for ' + request.proxy);
    }
    
    if (typeof request.authentication == 'object') {
      if (request.authentication.type) url += '&auth=' + request.authentication.type;
      if (request.authentication.moduleId) url += '&moduleId=' + request.authentication.moduleId;
      if (request.authentication.username) url += '&username=' + encodeURIComponent(request.authentication.username);
      if (request.authentication.password) url += '&password=' + encodeURIComponent(request.authentication.password);
      if (request.authentication.gp) url += '&gp=' + request.authentication.gp;
    }
      
    if (request.type && request.proxy) {
      url += '&type=' + request.type;
    }
    
    if (request.cache) {
      url += '&cache=' + request.cache;
    }
    
    if(UWA.Client.Engine.ie) {
      url += '&rnd='+ Math.random();
    }
    
    switch(request.type) {
      
      case 'json':
        if (this.useJsonRequest && typeof request.authentication == "undefined") {
          return UWA.Json.request(url, request);
        } else {
          var callback = request.onComplete;
          var context = request.context;
          request.onComplete = function() {
            UWA.Ajax.onCompleteJson(arguments, callback, context);
          }
          return UWA.Ajax.Request(url, request);
        }
      
      case 'xml':
        var callback = request.onComplete;
        request.onComplete = function() {
          UWA.Ajax.onCompleteXML(arguments, callback);
        }
        return UWA.Ajax.Request(url, request);
      
      case 'feed':
        var callback = request.onComplete;
        request.onComplete = function() {
          UWA.Ajax.onCompleteFeed(arguments, callback, context);
        }
        return UWA.Ajax.Request(url, request);
      
      default:
      case 'text':
      case 'html':
        var callback = request.onComplete;
        var context = request.context;
        request.onComplete = function() {
          UWA.Ajax.onCompleteText(arguments, callback, context);
        }
        return UWA.Ajax.Request(url, request);
    }
    
  },

  /* function here for compatibility :
	used in Dashboard	when the user clicks on 'OK' in preferences */

  saveDatas: function(moduleId, datas, callback) {
    var params = '';
    for (var key in datas) {
        if (datas[key] == null || typeof datas[key] == 'function' || datas[key] == 'lastUpdate') continue;
        if (params != '') params += '&';
        params += 'data[' + key + ']=' + encodeURIComponent(datas[key]);
    }
    var requestUrl = NV_PATH + 'data/save.php?id=' + moduleId;
    var request = { method: 'post', parameters: params };
    if (typeof callback == "function") request.onComplete = callback;
    this.request(requestUrl, request);
  }
  
};